package com.orderplus.opshop.core.template;

import com.orderplus.opshop.common.util.RequestLogUtils;
import com.orderplus.opshop.core.constants.enums.ResponseCodeConstant;
import com.orderplus.opshop.core.data.request.RequestParam;
import com.orderplus.opshop.core.data.response.ResponseData;
import com.orderplus.opshop.core.exception.CommonException;
import com.orderplus.opshop.core.exception.ParamErrorException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.dao.DuplicateKeyException;

import javax.validation.ConstraintViolationException;

/**
 * 公用抽象模板
 * 调用Dao层抽象模板，不支持分页
 * author:maihj
 *
 * @param <Request>  最外层请求对象
 * @param <Response> 最外层结果对象
 */
@Slf4j
public abstract class SingleTemplate<Request, Response> {

	/**
	 * 外层call
	 *
	 * @param request
	 * @return
	 */
	public ResponseData<Response> call(RequestParam<Request> request) {
		ResponseData<Response> response = new ResponseData<Response>();
		try {
//            if(!StringUtils.isEmpty(SpringContextUtil.getApplicationName())) {
//                request.setAppName(SpringContextUtil.getApplicationName());
//            }
			request.setTraceId(RequestLogUtils.getCurTraceId(request));
			request.setOperLevel(RequestLogUtils.getCurOperLevel(request));
			//请求remote
			Response Response = callInner(request);
			response.setData(Response);
			response.setCode(ResponseCodeConstant.SUCCESS.getResponseCode());
			response.setMsg(ResponseCodeConstant.SUCCESS.getResponseDesc());
		} catch (ConstraintViolationException e) {
			ConstraintViolationException cvException = (ConstraintViolationException) e;
			response.setCode(ResponseCodeConstant.REQUEST_ILLEGAL.getResponseCode());
			response.setMsg(ExceptionUtils.getMessage(cvException));
		} catch (ParamErrorException e) {
			response.setCode(e.getCode());
			response.setMsg(e.getMessage());
		} catch (CommonException e) {
			response.setCode(e.getCode());
			response.setMsg(e.getMessage());
		} catch (DuplicateKeyException e) {
			log.error("DuplicateKeyException错误,类:[{}],异常:", this.getClass().getName(), e);
			response.setCode(ResponseCodeConstant.DB_EXCEPTION.getResponseCode());
			response.setMsg("存在不可重复数据:" + e.getCause().getMessage());
		} catch (Exception e) {
			log.error("Exception错误,类:[{}],异常:", this.getClass().getName(), e);
			response.setCode(ResponseCodeConstant.SYS_EXCEPTION.getResponseCode());
			response.setCode(ResponseCodeConstant.SYS_EXCEPTION.getResponseCode());
			response.setMsg(ResponseCodeConstant.SYS_EXCEPTION.getResponseDesc());
		}
		return response;
	}

	/**
	 * 子类模板实现：request转换 -> 请求remote -> response转换
	 */
	protected abstract Response callInner(RequestParam<Request> request) throws Exception;
}
